#ifndef __INTERRUPT_H__
#define __INTERRUPT_H__

#include "linux/arch.h"
#include "linux/atomic.h"
#include "linux/wait.h"
#include "linux/irqflags.h"
#include "linux/irqdesc.h"
#include "linux/common.h"

typedef enum irqreturn irqreturn_t;

typedef irqreturn_t (*irq_handler_t)(int, void *);

struct irqaction
{
    irq_handler_t handler;
    void *dev_id;
    struct irqaction *next;
    unsigned int flags;
    char *name;
    unsigned int irq;
	irq_handler_t		thread_fn;
    struct task_struct *thread;
    unsigned long thread_flags;
    unsigned long thread_mask;
};

typedef void (* irq_server)(void *);

typedef struct
{
    irq_server	 irq_handler;
    unsigned int irq_num;
    void 		 *priv;
}irq_handler;

enum irq_flag 
{
    IRQ_FLAG_LOW_LEVEL = 1,
    IRQ_FLAG_HIGH_LEVEL,
    IRQ_FLAG_FALLING_EDGE,
    IRQ_FLAG_RISING_EDGE,
    IRQ_FLAG_BOTH_EDGE,
};

#define IRQF_TRIGGER_NONE	0x00000000
#define IRQF_TRIGGER_RISING	0x00000001
#define IRQF_TRIGGER_FALLING	0x00000002
#define IRQF_TRIGGER_HIGH	0x00000004
#define IRQF_TRIGGER_LOW	0x00000008
#define IRQF_TRIGGER_MASK	(IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
#define IRQF_TRIGGER_PROBE	0x00000010


#define IRQF_DISABLED		0x00000020
#define IRQF_SHARED		0x00000080
#define IRQF_PROBE_SHARED	0x00000100
#define __IRQF_TIMER		0x00000200
#define IRQF_PERCPU		0x00000400
#define IRQF_NOBALANCING	0x00000800
#define IRQF_IRQPOLL		0x00001000
#define IRQF_ONESHOT		0x00002000
#define IRQF_NO_SUSPEND		0x00004000
#define IRQF_FORCE_RESUME	0x00008000
#define IRQF_NO_THREAD		0x00010000
#define IRQF_EARLY_RESUME	0x00020000
#define IRQF_COND_SUSPEND	0x00040000

#define IRQF_TIMER		(__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)

extern int setup_irq(unsigned int irq, struct irqaction *act);
extern int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long irqflags, char *devname, void *devid);

enum
{
	HI_SOFTIRQ=0,
	TIMER_SOFTIRQ,
	NET_TX_SOFTIRQ,
	NET_RX_SOFTIRQ,
	BLOCK_SOFTIRQ,
	IRQ_POLL_SOFTIRQ,
	TASKLET_SOFTIRQ,
	SCHED_SOFTIRQ,
	HRTIMER_SOFTIRQ, 
	RCU_SOFTIRQ,    

	NR_SOFTIRQS
};

#define SOFTIRQ_STOP_IDLE_MASK (~(1 << RCU_SOFTIRQ))
extern char *softirq_to_name[NR_SOFTIRQS];
struct softirq_action
{
	void	(*action)(struct softirq_action *);
};

void do_softirq(void);
void __do_softirq(void);

#define set_softirq_pending(x) (local_softirq_pending() = (x))
#define or_softirq_pending(x)  (local_softirq_pending() |= (x))

#define force_irqthreads	(0)

struct tasklet_struct
{
	struct tasklet_struct *next;
	unsigned long state;
	atomic_t count;
	void (*func)(unsigned long);
	unsigned long data;
};

static inline int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,char *name, void *dev)
{
	return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}

extern int setup_irq_handler(unsigned int , irq_server, void *);
extern void kernel_enable_irq(void);
extern void kernel_disable_irq(void);
extern void enter_critical(void);
extern void exit_critical(void);
extern void early_irq_init(void);
extern void init_IRQ(void);

#endif

